package com.yhh.college_information_platform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yhh.college_information_platform.common.ResultCode;
import com.yhh.college_information_platform.constant.CommonConstant;
import com.yhh.college_information_platform.entity.Category;
import com.yhh.college_information_platform.entity.Resource;
import com.yhh.college_information_platform.exception.BusinessException;
import com.yhh.college_information_platform.mapper.CategoryMapper;
import com.yhh.college_information_platform.mapper.ResourceMapper;
import com.yhh.college_information_platform.service.CategoryService;
import com.yhh.college_information_platform.vo.CategoryVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 分类Service实现类
 *
 * @author yhh
 * @date 2025-10-25
 */
@Slf4j
@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private ResourceMapper resourceMapper;

    @Override
    public List<CategoryVO> getCategoryTree() {
        // 1. 查询所有启用的分类
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getStatus, CommonConstant.USER_STATUS_ENABLED)
                .orderByAsc(Category::getSortOrder);
        List<Category> allCategories = categoryMapper.selectList(wrapper);

        // 2. 转换为VO并设置资料数量
        List<CategoryVO> allCategoryVOs = allCategories.stream()
                .map(category -> {
                    CategoryVO vo = BeanUtil.copyProperties(category, CategoryVO.class);
                    // 统计该分类下的资料数量
                    vo.setResourceCount(getResourceCountByCategory(category.getId()));
                    return vo;
                })
                .collect(Collectors.toList());

        // 3. 构建树形结构
        return buildCategoryTree(allCategoryVOs, 0L);
    }

    @Override
    public List<CategoryVO> getFirstLevelCategories() {
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getParentId, 0)
                .eq(Category::getStatus, CommonConstant.USER_STATUS_ENABLED)
                .orderByAsc(Category::getSortOrder);
        
        List<Category> categories = categoryMapper.selectList(wrapper);
        return categories.stream()
                .map(category -> {
                    CategoryVO vo = BeanUtil.copyProperties(category, CategoryVO.class);
                    // 统计该分类下的资料数量
                    vo.setResourceCount(getResourceCountByCategory(category.getId()));
                    return vo;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<CategoryVO> getCategoriesByParentId(Long parentId) {
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getParentId, parentId)
                .eq(Category::getStatus, CommonConstant.USER_STATUS_ENABLED)
                .orderByAsc(Category::getSortOrder);
        
        List<Category> categories = categoryMapper.selectList(wrapper);
        return categories.stream()
                .map(category -> BeanUtil.copyProperties(category, CategoryVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public CategoryVO getCategoryById(Long id) {
        Category category = categoryMapper.selectById(id);
        if (category == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR, "分类不存在");
        }
        return BeanUtil.copyProperties(category, CategoryVO.class);
    }

    /**
     * 递归构建分类树
     *
     * @param allCategories 所有分类
     * @param parentId 父分类ID
     * @return 分类树
     */
    private List<CategoryVO> buildCategoryTree(List<CategoryVO> allCategories, Long parentId) {
        List<CategoryVO> result = new ArrayList<>();
        
        for (CategoryVO category : allCategories) {
            if (category.getParentId().equals(parentId)) {
                // 递归查找子分类
                List<CategoryVO> children = buildCategoryTree(allCategories, category.getId());
                category.setChildren(children);
                result.add(category);
            }
        }
        
        return result;
    }

    /**
     * 统计分类下的资料数量
     * 如果是一级分类，统计所有子分类的资料总数
     * 如果是二级分类，统计该分类的资料数
     *
     * @param categoryId 分类ID
     * @return 资料数量
     */
    private Integer getResourceCountByCategory(Long categoryId) {
        Category category = categoryMapper.selectById(categoryId);
        if (category == null) {
            return 0;
        }

        if (category.getLevel() == 1) {
            // 一级分类，统计所有子分类的资料
            LambdaQueryWrapper<Category> catWrapper = new LambdaQueryWrapper<>();
            catWrapper.eq(Category::getParentId, categoryId);
            List<Category> subCategories = categoryMapper.selectList(catWrapper);

            if (subCategories.isEmpty()) {
                // 如果没有子分类，直接统计该分类的资料
                return countResourcesByCategory(categoryId);
            }

            // 统计所有子分类的资料总数
            List<Long> categoryIds = subCategories.stream()
                    .map(Category::getId)
                    .collect(Collectors.toList());

            LambdaQueryWrapper<Resource> resWrapper = new LambdaQueryWrapper<>();
            resWrapper.in(Resource::getCategoryId, categoryIds)
                    .eq(Resource::getStatus, 1); // 只统计审核通过的
            return Math.toIntExact(resourceMapper.selectCount(resWrapper));
        } else {
            // 二级分类，直接统计该分类的资料
            return countResourcesByCategory(categoryId);
        }
    }

    /**
     * 统计指定分类的资料数量
     */
    private Integer countResourcesByCategory(Long categoryId) {
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resource::getCategoryId, categoryId)
                .eq(Resource::getStatus, 1); // 只统计审核通过的
        return Math.toIntExact(resourceMapper.selectCount(wrapper));
    }
}

